import {RasterBrush} from "./RasterBrush";

/**
 * 作者:hanbo
 * 日期:2018/11/1915:39
 * 描述:
 */

let FSHADER_SOURCE =
    `#ifdef GL_ES
     #ifdef GL_FRAGMENT_PRECISION_HIGH
     precision highp float;
     #else
     precision mediump float;
     #endif
     #endif
     uniform sampler2D u_Sampler;
     varying vec2 v_TexCoord;
     void main() {
         gl_FragColor = texture2D(u_Sampler, v_TexCoord);
     }`;

let VSHADER_SOURCE =
    `attribute vec4 a_Position;
     attribute vec2 a_TexCoord;
     varying vec2 v_TexCoord;
     uniform mat4 u_Matrix;
     
     void main() {
       gl_Position = u_Matrix * a_Position;
       v_TexCoord = a_TexCoord;
     }`;

export class ImageBrush extends RasterBrush {
    constructor(webGL, textureIndex) {
        super(webGL, VSHADER_SOURCE, FSHADER_SOURCE);
        this._textureIndex = textureIndex;
    }

    /**
     * 绘制图片
     * @param imageUrl
     * @param x0
     * @param y0
     * @param x1
     * @param y1
     */
    drawImage(imageUrl, x0 = 0, y0 = 0, x1 = 0, y1 = 0) {
        let image = new Image();  // 创造图像
        if (!image) {
            console.error('生成图像失败');
        }
        this.x0 = x0;
        this.x1 = x1;
        this.y0 = y0;
        this.y1 = y1;
        this.onload = false;
        const that = this;
        // 图像加载后，加载材质
        image.onload = function () {
            that.onload = true;
            that.image = image;
        };
        image.src = imageUrl;
    }

    /**
     * 绘制已加载完成图片图片
     * @param image
     * @param x0
     * @param y0
     * @param x1
     * @param y1
     * @param z {Number}
     */
    drawImageLoad(image, x0 = 0, y0 = 0, x1 = 0, y1 = 0, z = 0) {
        //检测大小，交换位置
        if (x0 > x1) {
            [x0, x1] = [x1, x0];
        }
        if (y0 > y1) {
            [y0, y1] = [y1, y0];
        }
        this.verticesTexCoords = new Float32Array([
            x0, y1, z, 0.0, 1.0,
            x0, y0, z, 0.0, 0.0,
            x1, y1, z, 1.0, 1.0,
            x1, y0, z, 1.0, 0.0
        ]);
        this.onload = true;
        this.image = image;
    }

    /**
     * 加载材质
     * @param gl
     * @param n
     * @param texture
     * @param u_Sampler
     * @param image
     * @param index [number] 纹理索引
     */
    static loadTexture(gl, n, texture, u_Sampler, image, index = 0) {
        // 开启材质0
        gl.activeTexture(gl.TEXTURE0 + index);
        // gl.activeTexture(gl.TEXTURE0);
        //绑定材质
        gl.bindTexture(gl.TEXTURE_2D, texture);
        // 设置材质参数
        // gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);//.TEXTURE_MIN_FILTER：缩小方法    默认：gl.NEAREST_MIPMAP_LINEAR
        // gl.NEAREST
        // 最临近过滤，获得最靠近纹理坐标点的像素
        // gl.LINEAR
        // 线性插值过滤，获取坐标点附近4个像素的加权平均值
        // gl.NEAREST_MIPMAP_NEAREST
        // 选择最邻近的mip层，并使用最邻近过滤
        // gl.NEAREST_MIPMAP_LINEAR
        // 在mip层之间使用线性插值和最邻近过滤
        // gl.LINEAR_MIPMAP_NEAREST
        // 选择最邻近的mip层，使用线性过滤
        // gl.LINEAR_MIPMAP_LINEAR
        // 在mip层之间使用线性插值和使用线性过滤
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);//TEXTURE_MAX_FILTER：放大方法   默认：gl.LINEAR
        // gl.NEAREST
        // 最临近过滤，获得最靠近纹理坐标点的像素
        // gl.LINEAR
        // 线性插值过滤，获取坐标点附近4个像素的加权平均值

        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);//水平填充方法   默认：gl.REPEAT
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);//垂直填充方法   默认：gl.REPEAT
        // gl.REPEAT	范围外的值进行重复处理	1.25 = 0.25 : -0.25 = 0.75
        // gl.MIRRORED_REPEAT	范围外的值进行镜像重复处理	1.25 = 0.75 : -0.25 = 0.25
        // gl.CLAMP_TO_EDGE	将值控制在0-1之间,不要求图片的大小为2的幂

        // gl.generateMipmap(gl.TEXTURE_2D);
        // 设置材质图像
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image);
        // 将材质0传递给取样器
        gl.uniform1i(u_Sampler, index);
        // gl.uniform1i(u_Sampler, 0);
        gl.drawArrays(gl.TRIANGLE_STRIP, 0, n); // 进行绘制
    }

    onImageLoad(image) {

        let n = 4; // 顶点数量
        this.createBuffer(this.verticesTexCoords);

        let FSIZE = Float32Array.BYTES_PER_ELEMENT;
        //获取attribute位置，开启缓冲
        this._a_Position = this._webGL.getAttribLocation(this._program, 'a_Position');

        if (this._a_Position < 0) {
            console.log('获取 a_Position失败');
            return;
        }
        this._webGL.vertexAttribPointer(this._a_Position, 3, this._webGL.FLOAT, false, FSIZE * 5, 0);
        this._webGL.enableVertexAttribArray(this._a_Position);

        this._a_TexCoord = this._webGL.getAttribLocation(this._program, 'a_TexCoord');
        if (this._a_TexCoord < 0) {
            console.log('获取a_TexCoord失败');
            return -1;
        }
        this._webGL.vertexAttribPointer(this._a_TexCoord, 2, this._webGL.FLOAT, false, FSIZE * 5, FSIZE * 3);
        this._webGL.enableVertexAttribArray(this._a_TexCoord);

        let texture = this._webGL.createTexture();   // Create a texture object
        if (!texture) {
            console.error('生成材质失败');
        }

        // 获取取样器位置
        let u_Sampler = this._webGL.getUniformLocation(this._program, 'u_Sampler');
        if (!u_Sampler) {
            console.error('获取取样器内存失败');
        }
        ImageBrush.loadTexture(this._webGL, n, texture, u_Sampler, image, this._textureIndex);
    }

    // /**
    //  * 将数据存进缓冲区
    //  * @param data {Float32Array}
    //  * @returns {boolean}
    //  */
    // createBuffer(data) {
    //     //如果缓冲区不存在，则新建缓冲区
    //     if (!this._vertexColorBuffer) {
    //         //创建缓冲区
    //         this._vertexColorBuffer = this._webGL.createBuffer();
    //         if (!this._vertexColorBuffer) {
    //             console.log('生成缓冲区失败');
    //             return false;
    //         }
    //         //绑定缓冲区
    //         this._webGL.bindBuffer(this._webGL.ARRAY_BUFFER, this._vertexColorBuffer);
    //     }
    //     //向缓冲区写入数据
    //     this._webGL.bufferData(this._webGL.ARRAY_BUFFER, data, this._webGL.STATIC_DRAW);
    // }

    draw(projection) {
        if (this.onload) {
            super.draw(projection);
            this.onImageLoad(this.image, this.x0, this.y0, this.x1, this.y1, this.z);
        }
    }

    /**
     * 清理WebGL占用
     */
    clear() {
        super.clear();
        this._webGL.disableVertexAttribArray(this._a_TexCoord);
        this._webGL.disableVertexAttribArray(this._a_Position);

    }
}